home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Arashi 1.1.1 / source code / For your think c folder / VA Kit ƒ / VABuffers.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-31  |  9.1 KB  |  393 lines  |  [TEXT/KAHL]

  1. /*/
  2.      Project Arashi: VABuffers.c
  3.      Major release: Version 1.1d2, 9/5/95
  4.  
  5.      Last modification: Thursday, August 31, 1995, 1:22
  6.      Created: Thursday, February 9, 1989, 15:21
  7.  
  8.      Copyright © 1989-1995, Juri Munkki
  9. /*/
  10.  
  11. /*
  12. **    In addition to the VAInit and VAClose calls,
  13. **    this files contains routines that manage the
  14. **    double buffering of the vector animation toolkit.
  15. */
  16.  
  17. #define VECTOR_ANIMATION_MAIN
  18. #define     _VABUFFERS_
  19. #include <Palettes.h>
  20. #include <Retrace.h>
  21. #include <Slots.h>
  22. #include "VA.h"
  23. #include "VAInternal.h"
  24. #include "Video.h"
  25.  
  26. #define    NO_VIDEO_BLANK_ROUTINE
  27.  
  28. extern    ColorSpec    *VASpec[2];        /*    VA color tables.    */
  29.  
  30. /*
  31. >>    If A5 points to a VideoVars structure, the following macro will become
  32. >>    xx(A5), where xx is the offset into that structure element.
  33. */
  34. #define VIDB(field)        ((int) &((VideoVars *) 0)->field)(A5)
  35.  
  36. typedef    struct
  37. {
  38.     VBLTask                VBL;        /*    VBLTask entry                                */
  39.     int                    theslot;    /*    Slot number                                    */
  40.     int                    called;        /*    A flag                                        */
  41.     long                RealA5;        /*    A5 saved here.                                */
  42.     int                    changecolors;
  43.     VDSetEntryRecord    colorange;
  44.     CntrlParam            coloparam;
  45.  
  46. }    VideoVars;
  47.  
  48. static    VideoVars    VideoBlank;
  49.  
  50. #ifdef _UNUSED_CODE
  51. /*
  52. >>    SetUpVBLTask contains and sets up a VBL task that
  53. >>    changes the color lookup table to contain the current
  54. >>    set of colors. This code was used only for testing
  55. >>    a theory of mine and it caused more trouble than
  56. >>    it was good for.
  57. */
  58. void        VASetUpVideoTask(Display)
  59. GDHandle    Display;
  60. {
  61.     AuxDCEHandle    DisplayDriver;
  62.     
  63.     long    vbltask;
  64.  
  65.     asm    {
  66.         lea        @myvbltask,A0        ;    Get address of vbltask
  67.         move.l    A0,vbltask            ;    Store in local variable
  68.         lea        @mybase,A0            ;    Get addr of variable base storage
  69.         lea        VideoBlank,A1            ;    Get addr of VideoBlank record
  70.         move.l    A1,(A0)                ;    Store base in base storage
  71.         move.l    A5,VideoBlank.RealA5
  72.         }
  73.  
  74.     VideoBlank.VBL.qType=vType;                /*    Vertical blanking queue.    */
  75.     VideoBlank.VBL.vblAddr=(ProcPtr)vbltask;/*    Address of task                */
  76.     VideoBlank.VBL.vblCount=1;                /*    Every tick                    */
  77.     VideoBlank.VBL.vblPhase=0;                /*    0 is ok..                    */
  78.  
  79.     DisplayDriver=(void *)GetDCtlEntry((*Display)->gdRefNum);
  80.     VideoBlank.theslot=(*DisplayDriver)->dCtlSlot;
  81.     SlotVInstall(&VideoBlank.VBL,VideoBlank.theslot);    /*    Use main display VBL queue.    */
  82.     return;
  83.     
  84. /*
  85. >>    This is the actual VBL task that gets executed.
  86. >>    It just increments a counter and sets a flag
  87. >>    every time it's called.
  88. */
  89. asm    {
  90. @myvbltask
  91.         move.l    A5,-(SP)                ;    Save A5
  92.         move.l    @mybase,A5                ;    Get VideoBlank address into A5
  93.         move.w    #1,VIDB(VBL.vblCount)    ;    Call again.
  94.         move.w    #1,VIDB(called)            ;    Flag screen blank
  95.         
  96.         move.w    VIDB(changecolors),D0
  97.         beq.s    @donothing
  98.  
  99.         clr.w    VIDB(changecolors)        
  100.         lea        VIDB(coloparam),A0
  101.         _PBControl    IMMED
  102.         
  103. @donothing
  104.         move.l    (sp)+,A5
  105.         rts
  106. @mybase
  107.         dc.l    0                        ;    VideoBlank record address stored here.
  108.  
  109.     }
  110. }
  111. #endif
  112.  
  113. /*
  114. >>    VADoFrame is called when the vector animation
  115. >>    kit is not "late" and should draw new lines and
  116. >>    points on the screen. After drawing, it switches
  117. >>    display buffers and then erases the now invisible
  118. >>    old graphics.
  119. */
  120. void    VADoFrame()
  121. {
  122.     register    int        i,erasedbuffer;
  123.                 int        oldcolor;
  124.     register    Rect    *p;
  125.     register    int        *c;
  126.                 int        mode;
  127.  
  128.     
  129.     oldcolor=VA.color;
  130.  
  131.     VA.field=3;
  132.  
  133.     if(VA.visbuffer)    VA.offset=2;
  134.         else            VA.offset=5;
  135.  
  136.     mode=QD32COMPATIBLE;
  137.  
  138.     erasedbuffer = VA.curbuffer-2;
  139.     if(erasedbuffer<0) erasedbuffer+=3;
  140.  
  141.     VAInsertExplosions();
  142.  
  143.     SwapMMUMode(&mode);
  144.     VA.SkipFrames = VA.numlines[erasedbuffer];
  145.     VAEraseBufferedLines(    VA.numlines[erasedbuffer],    VA.lines[erasedbuffer]);
  146.     VAErasePixels(            VA.numpix[erasedbuffer],    VA.pix[erasedbuffer]);
  147.     VAEraseSpots(            VA.numspots[erasedbuffer],    VA.spots[erasedbuffer]);
  148.  
  149.     VAPlotSpots(VA.numspots[VA.curbuffer],
  150.                 VA.spots[VA.curbuffer],
  151.                 VA.spotcolors[VA.curbuffer]);
  152.  
  153.     VADrawBufferedLines(VA.numlines[VA.curbuffer],
  154.                         VA.lines[VA.curbuffer],
  155.                         VA.linecolors[VA.curbuffer]);
  156.  
  157.     VAPlotPixels(VA.numpix[VA.curbuffer],
  158.                 VA.pix[VA.curbuffer],
  159.                 VA.pixcolors[VA.curbuffer]);
  160.     SwapMMUMode(&mode);
  161.  
  162. #ifdef    OLDSETENTRIES
  163.     SetGDevice(VA.device);
  164.     SetEntries(0,255,VASpec[VA.visbuffer]);
  165. #else
  166.  
  167.     VideoBlank.colorange.csTable=VASpec[VA.visbuffer];
  168.     VideoBlank.colorange.csStart=0;
  169.     VideoBlank.colorange.csCount=255;
  170.  
  171.     *(void **)(&VideoBlank.coloparam.csParam)= &VideoBlank.colorange;
  172.     VideoBlank.coloparam.ioCompletion=0;
  173.     VideoBlank.coloparam.ioCRefNum=VA.refnum;
  174.     VideoBlank.coloparam.csCode=3;
  175.     
  176. #ifdef _UNUSED_CODE
  177.     VideoBlank.changecolors = 1;
  178.     while(VideoBlank.changecolors);
  179. #endif
  180.     
  181.     PBControl(&VideoBlank.coloparam,0);
  182.  
  183. #endif
  184.  
  185.     VA.numlines[erasedbuffer]=0;
  186.     VA.numpix[erasedbuffer]=0;
  187.     VA.numspots[erasedbuffer]=0;
  188.  
  189.     VA.curbuffer = erasedbuffer;
  190.     VA.visbuffer = 1-VA.visbuffer;
  191.  
  192.     VA.color=oldcolor;
  193. }
  194.  
  195. /*
  196. >>    VACancelFrame is called when the kit is late
  197. >>    and it has not time to draw new graphics. Any
  198. >>    new buffered drawing commands are just flushed
  199. >>    away and no buffer switching is done. Note that
  200. >>    explosions have to be advanced one frame or they
  201. >>    will slow down.
  202. */
  203. void    VACancelFrame()
  204. {
  205.     VAInsertExplosions();
  206.     VA.numlines[VA.curbuffer]=0;
  207.     VA.numpix[VA.curbuffer]=0;
  208.     VA.numspots[VA.curbuffer]=0;
  209. }
  210.  
  211. CTabHandle    SystemCTab;    /*    Used for restoring colors when STORM is done.    */
  212.  
  213. /*
  214. >>    Start up the vector animation kit with VAInit.
  215. */
  216. void    VAInit(GDev)
  217. GDHandle    GDev;
  218. {
  219.     register    int                i,j;
  220.     register    PixMapPtr        Pix;
  221.     register    Ptr                quickp;
  222.     register    GDHandle        savedgd;
  223.                 int                reqlist[257];
  224.                 int                zero=0;
  225.  
  226.     while((*(*GDev)->gdPMap)->pixelSize != 8)
  227.     {    i=Alert(200,0);
  228.         if(i==2)    ExitToShell();
  229.     }
  230.     HideCursor();
  231.  
  232.     /*    Save color table for display device we are going to use:    */
  233.     savedgd=GetGDevice();
  234.     SetGDevice(GDev);
  235.     SystemCTab=(CTabHandle)NewHandle(0);
  236.     for(i=0;i<256;i++)
  237.     {    reqlist[i+1]=i;
  238.     }
  239.     reqlist[0]=255;
  240.     SaveEntries(0,SystemCTab,reqlist);
  241.     VAInstallQDSearch();
  242.     SetGDevice(savedgd);
  243.  
  244.     /*    Open a window that covers our device as completely as possible:    */
  245.     VA.window=(WindowPtr)NewCWindow(0,&(*GDev)->gdRect,&zero,-1,plainDBox,(void *)-1,0,0);
  246.     RectRgn(VA.window->visRgn,&VA.window->portRect);
  247.     SetPort(VA.window);
  248.     
  249.     /*    Set up an explicit palette for direct color indexing:            */
  250.     VA.palette=(Handle)NewPalette(256,0,pmExplicit,0);
  251.     SetPalette(VA.window,VApalette,0);
  252.  
  253.     /*    Initialize some important global variables:                        */
  254.     Pix=*(*GDev)->gdPMap;
  255.     VA.base=Pix->baseAddr;
  256.     VA.row=Pix->rowBytes & 0x3FFF;
  257.     VA.frame=VA.window->portRect;
  258.     VA.DisplayFrame=(*GDev)->gdRect;
  259.     VA.device=(Handle)GDev;
  260.     VA.refnum=(*GDev)->gdRefNum;
  261.  
  262.     quickp=VA.base;
  263.         
  264.     VA.quickrow=(Ptr *)NewPtr(VA.frame.bottom*sizeof(Ptr));
  265.     for(i=0;i<VA.frame.bottom;i++)
  266.     {    VA.quickrow[i]=quickp;
  267.         quickp+=VA.row;
  268.     }
  269.  
  270.     VA.ticker=QuickTicks+3;    /*    QuickTicks is just an alias for TickCount()    */
  271.     VA.field=3;
  272.     VA.offset=2;
  273.  
  274.     /*    Allocate space for display lists etc. (double buffered)            */
  275.     for(i=0;i<NUMDISPLISTS;i++)
  276.     {    VASpec[i]        = (void *) NewPtr(sizeof(ColorSpec)    * 256);
  277.         VA.lines[i]        = (void *) NewPtr(sizeof(Rect)        * MAXSAVED);
  278.         VA.linecolors[i]= (void *) NewPtr(sizeof(int)        * MAXSAVED);
  279.         VA.pixcolors[i] = (void *) NewPtr(sizeof(int)        * MAXSAVEDPIX);
  280.         VA.pix[i]        = (void *) NewPtr(sizeof(Ptr)        * MAXSAVEDPIX);
  281.         VA.spotcolors[i]= (void *) NewPtr(sizeof(int)        * MAXSAVEDPIX);
  282.         VA.spots[i]        = (void *) NewPtr(sizeof(Ptr)        * MAXSAVEDPIX);
  283.         VA.numlines[i]=0;
  284.         VA.numpix[i]=0;
  285.         VA.numspots[i]=0;
  286.     }
  287.     VACreateColorMapping();
  288.  
  289.     
  290.     VAEraseBuffer();
  291.     
  292. #ifdef    VIDEO_BLANK_ROUTINE
  293.     VASetUpVideoTask(GDev);
  294. #endif
  295.     VASetColors(GetResource('CLOT',1000));
  296.     VA.curbuffer=0;
  297.     VA.visbuffer=1;
  298.     VA.FrameSpeed=DEFAULT_FRAMESPEED;
  299.     VALoadExplosions();
  300.     VAInitSins();
  301.     VADoFrame();
  302. }
  303.  
  304. /*
  305. >>    Call VARestoreColors to temporarily
  306. >>    restore the color environment that
  307. >>    existed before the vector animation
  308. >>    kit took control.
  309. */
  310. void    VARestoreColors()
  311. {
  312.     register    GDHandle    savedgd;
  313.     register    int            i;
  314.                 int            reqlist[257];
  315.  
  316.     for(i=0;i<256;i++)
  317.     {    reqlist[i+1]=i;
  318.     }
  319.     reqlist[0]=255;
  320.  
  321.     savedgd=GetGDevice();
  322.     SetGDevice(VA.device);
  323.  
  324.     RestoreEntries(SystemCTab,0,reqlist);
  325.     VARemoveQDSearch();
  326.  
  327.     SetGDevice(savedgd);
  328. }
  329. /*
  330. >>    VAClose restores the old color environment, but doesn't
  331. >>    do much else. It doesn't free any of the storage that
  332. >>    was previously aquired, although it probably should...
  333. >>
  334. >>    Maybe some day I'll bother to write a proper VAClose.
  335. */
  336. void    VAClose()
  337. {
  338.  
  339. #ifdef    VIDEO_BLANK_ROUTINE
  340.     SlotVRemove(&VideoBlank.VBL,VideoBlank.theslot);
  341. #endif
  342.  
  343.     VARestoreColors();
  344.     ShowCursor();
  345. }
  346.  
  347. /*
  348. >>    VAStep performs one animation step.
  349. >>    There's still a busy waiting loop in
  350. >>    here, but usually it's not used much.
  351. */
  352. void    VAStep()
  353. {
  354.     VA.FrameCounter++;
  355.     
  356.     if(VA.Late)
  357.     {    VACancelFrame();
  358.         VA.SkipFrames++;
  359.         VA.SkipCounter++;
  360.     }
  361.     else
  362.     {    VADoFrame();
  363.         VA.SkipCounter=0;
  364.     }
  365.  
  366.     /*    Determine if we are late:
  367.     */
  368.     VA.ticker+=VA.FrameSpeed;
  369.     VA.Late=VA.ticker<=QuickTicks;
  370.     if(VA.SkipCounter>=4)
  371.         VA.Late=0;    /*    Don't skip more than 4 frames in a row.    */
  372.  
  373.     /*    If we are ahead more than 4 ticks, loop for a while.
  374.     */
  375.     while(VA.ticker>QuickTicks+4);
  376. }
  377.  
  378. /*
  379. >>    Call VACatchUp when you have stopped
  380. >>    using VAStep for a while. If you do
  381. >>    a lengthy drawing without calling
  382. >>    VAStep regularly, the animation kit
  383. >>    will think that it is badly late and
  384. >>    the animation will skip wildly. Calling
  385. >>    VACatchUp before resuming the animation
  386. >>    will solve this problem.
  387. */
  388. void    VACatchUp()
  389. {
  390.     VA.SkipCounter=0;
  391.     VA.Late=0;
  392.     VA.ticker=QuickTicks+VA.FrameSpeed;
  393. }